#pragma once
#include "InventoryItem.hpp"
#include "CItem.hpp"
#include "PC.h"
#include "CSkill.hpp"
#include "NetLib/MemoryMgr.h"
#include "struct.hpp"
#include "std/list"
#include "std/map"
class CMsg;
class CNPC;


class CCharacterMgr
{
	/* this+  0 */ public: //const CCharacterMgr::`vftable';
	/* this+  4 */ private: CPC** m_PC;
	/* this+  8 */ private: int m_PCCount;
	/* this+ 12 */ private: long m_curPlayChar;
	/* this+ 16 */ private: long m_curValidPlayChar;
	/* this+ 20 */ private: long m_curDisconnectCountPlayChar;
	/* this+ 24 */ private: CMemoryMgr<CPC> m_pcMemoryPool;
	/* this+ 72 */ private: CMemoryMgr<CItem> m_itemMemoryPool;
	/* this+120 */ private: CMemoryMgr<CSkill> m_skillMemoryPool;
	/* this+168 */ private: mystd::map<unsigned long,CItem*> m_item;
	/* this+180 */ private: mystd::map<unsigned long,CSkill*> m_skill;
	/* this+192 */ private: mystd::map<int,CNPC*> m_npcMap;
	/* this+204 */ private: mystd::list<int> m_AIDPool;
	/* this+216 */ private: RTL_CRITICAL_SECTION m_csPC;
	/* this+240 */ private: mystd::map<unsigned long,PC_INDEX_DATA> m_pcNonclusteredIndex;
	/* this+252 */ private: mystd::map<CMapRes*,mystd::list<CNPC*> > m_warpNPCList;
	/* this+264 */ private: mystd::map<int,int> m_bossInMap;

	public: CCharacterMgr::CCharacterMgr(void);
	public: virtual CCharacterMgr::~CCharacterMgr(void);
	public: void CCharacterMgr::Init(int MaxCharacterCount);
	public: int CCharacterMgr::AddCharacter(CCharacter* pCharacter);
	public: void CCharacterMgr::RemoveCharacter(CCharacter* pCharacter);
	public: void CCharacterMgr::Free(CCharacter* pc);
	public: CItem* CCharacterMgr::AllocItem(void);
	public: CItem* CCharacterMgr::CreateItem(CITP* itp, ITEM_INFO* itemInfo);
	public: CItem* CCharacterMgr::GetNeighborhoodItem(short xPos, short yPos, short Range, CMapRes* mapRes);
	public: CSkill* CCharacterMgr::AllocSkill(void);
	public: CSkill* CCharacterMgr::CreateSkill2(const unsigned int in_SKGroupUniqueID, short x, short y, CMapRes* mapRes, int job, unsigned long creatorAID, unsigned long expiredTime, short level, unsigned short SKID, int par1, int par2, int cellflag);
	public: CSkill* CCharacterMgr::GetSkillWithSKGroupUniqueID(const int in_myXpost, const int in_myYpos, const unsigned int in_SKGroupUniqueID);
	public: CSkill* CCharacterMgr::GetSkill(int skillID, int xPos, int yPos, CMapRes* mapRes);
	public: CSkill* CCharacterMgr::GetSkill(int xPos, int yPos, CMapRes* mapRes);
	public: int CCharacterMgr::GetSkillList(int xPos, int yPos, mystd::vector<CSkill *>& skList, CCharacter* exceptChar, CMapRes* mapRes);
	public: void CCharacterMgr::DestroyAllNPC(void);
	public: CNPC* CCharacterMgr::AddNPC(void* p, unsigned long parentAID);
	public: int CCharacterMgr::GetMonsterCount(void);
	public: void CCharacterMgr::SendMsgFromNPCServer(unsigned long senderAID, unsigned long receiverAID, CMsg* msg, unsigned long par1, unsigned long par2);
	public: void CCharacterMgr::SendToNPCServer(int len, const char* buf);
	public: void CCharacterMgr::RegisterBossInMap(CNPC* npc);
	public: CNPC* CCharacterMgr::FindBossInMap(int mapResID);
	public: bool CCharacterMgr::CheckChashTraderNpc(void);
	public: unsigned char CCharacterMgr::GetNpcType(unsigned long AID);
	public: void CCharacterMgr::ClearBossInMap(void);
	public: CPC* CCharacterMgr::AllocPC(void);
	public: CPC* CCharacterMgr::FindPCByGID(unsigned long GID);
	public: int CCharacterMgr::FindPC(CCharacter* pCharacter);
	public: int CCharacterMgr::GetPCCountIntheMap(char* mapName);
	public: int CCharacterMgr::GetPCFreeSize(void);
	public: CPC* CCharacterMgr::FindCharacterByIndex(unsigned long AID, int Index);
	public: CCharacter* CCharacterMgr::FindCharacter(unsigned long AID, unsigned long Type);
	public: CPC* CCharacterMgr::FindCharacter(const char* characterName);
	public: unsigned long CCharacterMgr::GetAID(void);
	public: void CCharacterMgr::PutAID(unsigned long AID);
	public: CCharacter* CCharacterMgr::FastFindCharacter(unsigned long aID);
	public: int CCharacterMgr::SendMsg(CCharacter* sender, CCharacter* receiver, unsigned long msgID, int par1, int par2, int par3, MSGpar::CVar par4);
	public: int CCharacterMgr::SendMsg(CCharacter* sender, unsigned long receiverID, unsigned long msgID, int par1, int par2, int par3, MSGpar::CVar par4);
	public: void CCharacterMgr::SendCommand(unsigned long AID, CITZMsg* reqMsg);
	public: char* CCharacterMgr::GetCharName(unsigned long AID);
	public: void CCharacterMgr::GetVar(unsigned long AID, CMsg* reqMsg, CMsg* ansMsg);
	public: void CCharacterMgr::GetVarFromPC(unsigned long AID, CMsg* reqMsg, CMsg* ansMsg);
	public: void CCharacterMgr::ProcessAllCharacter(void);
	public: void CCharacterMgr::Multicast(CMapRes* mapRes, int xPos, int yPos, int len, char* buf, int range);
	public: int CCharacterMgr::GetCurPlayChar(void);
	public: int CCharacterMgr::GetCurValidPlayChar(void);
	public: int CCharacterMgr::GetCurDisconnectCountPlayChar(void);
	public: void CCharacterMgr::BroadCast(int len, char* buf);
	public: void CCharacterMgr::BroadCastExceptME(int len, char* buf, const char* ID);
	public: void CCharacterMgr::SendToHServer(int len, const char* buf);
	public: void CCharacterMgr::SendToIServer(int len, const char* buf);
	public: IVItEquipItem* CCharacterMgr::GetEquipItem(unsigned long AID, unsigned long loc);
	public: char* CCharacterMgr::GetGuildName(unsigned long AID);
	public: void CCharacterMgr::AddWarpNpcList(CMapRes* mapRes, CNPC* npc);
	public: void CCharacterMgr::RemoveWarpNpcList(CMapRes* mapRes, CNPC* npc);
	public: mystd::list<CNPC *>* CCharacterMgr::GetWarpNpcList(CMapRes* mapRes);
	public: void CCharacterMgr::Flush(int mapID, int guildID, int target);
	public: int CCharacterMgr::GetSkillSize(void);
	public: void CCharacterMgr::InitLotto(void);
	public: short CCharacterMgr::GetDistance(CCharacter* src, CCharacter* dest);
	public: int CCharacterMgr::KickPlayerInMap(const int in_MapID);
	public: CPC* CCharacterMgr::GetOnePlayerInMap(const int in_MapID);
	public: void CCharacterMgr::FinalDungeon_Skill(const char* mapName);
	public: void CCharacterMgr::FinalDungeon_Item(const char* mapName);
	public: void CCharacterMgr::FinalDungeon_NpcEvent(const char* mapName);
	public: void CCharacterMgr::FinalDungeon_Npc(const char* mapName);
	public: void CCharacterMgr::BroadCastReAssemblyCertify(void);
	private: CNPC* CCharacterMgr::AllocNPC(unsigned char type);
	private: CNPC* CCharacterMgr::FindNPCByAID(unsigned long AID);
	private: CItem* CCharacterMgr::SearchItem(unsigned long AID);
	private: CSkill* CCharacterMgr::SearchSkill(unsigned long AID);
	private: void CCharacterMgr::AddPCToIndexInfo(unsigned long AID, int index, unsigned long connectionTime);
	private: CCharacter* CCharacterMgr::SearchPCFromIndexInfo(unsigned long AID);
	private: void CCharacterMgr::DeletePCFromIndexInfo(unsigned long AID);
	private: void CCharacterMgr::OnDisconnect(CPC* pc);
	private: void CCharacterMgr::OnDisconnect_STEP_NONE(CPC* pc);
	private: void CCharacterMgr::OnDisconnect_STEP_REMOVE(CPC* pc);
	private: void CCharacterMgr::OnDisconnect_STEP_ARRANGE(CPC* pc);
	private: void CCharacterMgr::OnDisconnect_STEP_ASYNCDB_SAVE_REQUEST(CPC* const pc);
	private: void CCharacterMgr::OnDisconnect_STEP_COMPLETE(CPC* pc);
	private: void CCharacterMgr::OnDisconnect_STEP_ASYNCDB_SAVE_COMPLETE(CPC* pc);
	private: int CCharacterMgr::IsSendable(CPC* pc);

private:
	static hook_method<void (CCharacterMgr::*)(int MaxCharacterCount)> CCharacterMgr::_Init;
	static hook_method<int (CCharacterMgr::*)(CCharacter* pCharacter)> CCharacterMgr::_AddCharacter;
	static hook_method<void (CCharacterMgr::*)(CCharacter* pCharacter)> CCharacterMgr::_RemoveCharacter;
	static hook_method<void (CCharacterMgr::*)(CCharacter* pc)> CCharacterMgr::_Free;
	static hook_method<CItem* (CCharacterMgr::*)(void)> CCharacterMgr::_AllocItem;
	static hook_method<CItem* (CCharacterMgr::*)(CITP* itp, ITEM_INFO* itemInfo)> CCharacterMgr::_CreateItem;
	static hook_method<CItem* (CCharacterMgr::*)(short xPos, short yPos, short Range, CMapRes* mapRes)> CCharacterMgr::_GetNeighborhoodItem;
	static hook_method<CSkill* (CCharacterMgr::*)(void)> CCharacterMgr::_AllocSkill;
	static hook_method<CSkill* (CCharacterMgr::*)(const unsigned int in_SKGroupUniqueID, short x, short y, CMapRes* mapRes, int job, unsigned long creatorAID, unsigned long expiredTime, short level, unsigned short SKID, int par1, int par2, int cellflag)> CCharacterMgr::_CreateSkill2;
	static hook_method<CSkill* (CCharacterMgr::*)(const int in_myXpost, const int in_myYpos, const unsigned int in_SKGroupUniqueID)> CCharacterMgr::_GetSkillWithSKGroupUniqueID;
	static hook_method<CSkill* (CCharacterMgr::*)(int skillID, int xPos, int yPos, CMapRes* mapRes)> CCharacterMgr::_GetSkill;
	static hook_method<CSkill* (CCharacterMgr::*)(int xPos, int yPos, CMapRes* mapRes)> CCharacterMgr::_GetSkill2;
	static hook_method<int (CCharacterMgr::*)(int xPos, int yPos, mystd::vector<CSkill *>& skList, CCharacter* exceptChar, CMapRes* mapRes)> CCharacterMgr::_GetSkillList;
	static hook_method<void (CCharacterMgr::*)(void)> CCharacterMgr::_DestroyAllNPC;
	static hook_method<CNPC* (CCharacterMgr::*)(void* p, unsigned long parentAID)> CCharacterMgr::_AddNPC;
	static hook_method<int (CCharacterMgr::*)(void)> CCharacterMgr::_GetMonsterCount;
	static hook_method<void (CCharacterMgr::*)(unsigned long senderAID, unsigned long receiverAID, CMsg* msg, unsigned long par1, unsigned long par2)> CCharacterMgr::_SendMsgFromNPCServer;
	static hook_method<void (CCharacterMgr::*)(int len, const char* buf)> CCharacterMgr::_SendToNPCServer;
	static hook_method<void (CCharacterMgr::*)(CNPC* npc)> CCharacterMgr::_RegisterBossInMap;
	static hook_method<CNPC* (CCharacterMgr::*)(int mapResID)> CCharacterMgr::_FindBossInMap;
	static hook_method<bool (CCharacterMgr::*)(void)> CCharacterMgr::_CheckChashTraderNpc;
	static hook_method<unsigned char (CCharacterMgr::*)(unsigned long AID)> CCharacterMgr::_GetNpcType;
	static hook_method<void (CCharacterMgr::*)(void)> CCharacterMgr::_ClearBossInMap;
	static hook_method<CPC* (CCharacterMgr::*)(void)> CCharacterMgr::_AllocPC;
	static hook_method<CPC* (CCharacterMgr::*)(unsigned long GID)> CCharacterMgr::_FindPCByGID;
	static hook_method<int (CCharacterMgr::*)(CCharacter* pCharacter)> CCharacterMgr::_FindPC;
	static hook_method<int (CCharacterMgr::*)(char* mapName)> CCharacterMgr::_GetPCCountIntheMap;
	static hook_method<int (CCharacterMgr::*)(void)> CCharacterMgr::_GetPCFreeSize;
	static hook_method<CPC* (CCharacterMgr::*)(unsigned long AID, int Index)> CCharacterMgr::_FindCharacterByIndex;
	static hook_method<CCharacter* (CCharacterMgr::*)(unsigned long AID, unsigned long Type)> CCharacterMgr::_FindCharacter;
	static hook_method<CPC* (CCharacterMgr::*)(const char* characterName)> CCharacterMgr::_FindCharacter2;
	static hook_method<unsigned long (CCharacterMgr::*)(void)> CCharacterMgr::_GetAID;
	static hook_method<void (CCharacterMgr::*)(unsigned long AID)> CCharacterMgr::_PutAID;
	static hook_method<CCharacter* (CCharacterMgr::*)(unsigned long aID)> CCharacterMgr::_FastFindCharacter;
	static hook_method<int (CCharacterMgr::*)(CCharacter* sender, CCharacter* receiver, unsigned long msgID, int par1, int par2, int par3, MSGpar::CVar par4)> CCharacterMgr::_SendMsg;
	static hook_method<int (CCharacterMgr::*)(CCharacter* sender, unsigned long receiverID, unsigned long msgID, int par1, int par2, int par3, MSGpar::CVar par4)> CCharacterMgr::_SendMsg2;
	static hook_method<void (CCharacterMgr::*)(unsigned long AID, CITZMsg* reqMsg)> CCharacterMgr::_SendCommand;
	static hook_method<char* (CCharacterMgr::*)(unsigned long AID)> CCharacterMgr::_GetCharName;
	static hook_method<void (CCharacterMgr::*)(unsigned long AID, CMsg* reqMsg, CMsg* ansMsg)> CCharacterMgr::_GetVar;
	static hook_method<void (CCharacterMgr::*)(unsigned long AID, CMsg* reqMsg, CMsg* ansMsg)> CCharacterMgr::_GetVarFromPC;
	static hook_method<void (CCharacterMgr::*)(void)> CCharacterMgr::_ProcessAllCharacter;
	static hook_method<void (CCharacterMgr::*)(CMapRes* mapRes, int xPos, int yPos, int len, char* buf, int range)> CCharacterMgr::_Multicast;
	static hook_method<int (CCharacterMgr::*)(void)> CCharacterMgr::_GetCurPlayChar;
	static hook_method<int (CCharacterMgr::*)(void)> CCharacterMgr::_GetCurValidPlayChar;
	static hook_method<int (CCharacterMgr::*)(void)> CCharacterMgr::_GetCurDisconnectCountPlayChar;
	static hook_method<void (CCharacterMgr::*)(int len, char* buf)> CCharacterMgr::_BroadCast;
	static hook_method<void (CCharacterMgr::*)(int len, char* buf, const char* ID)> CCharacterMgr::_BroadCastExceptME;
	static hook_method<void (CCharacterMgr::*)(int len, const char* buf)> CCharacterMgr::_SendToHServer;
	static hook_method<void (CCharacterMgr::*)(int len, const char* buf)> CCharacterMgr::_SendToIServer;
	static hook_method<IVItEquipItem* (CCharacterMgr::*)(unsigned long AID, unsigned long loc)> CCharacterMgr::_GetEquipItem;
	static hook_method<char* (CCharacterMgr::*)(unsigned long AID)> CCharacterMgr::_GetGuildName;
	static hook_method<void (CCharacterMgr::*)(CMapRes* mapRes, CNPC* npc)> CCharacterMgr::_AddWarpNpcList;
	static hook_method<void (CCharacterMgr::*)(CMapRes* mapRes, CNPC* npc)> CCharacterMgr::_RemoveWarpNpcList;
	static hook_method<mystd::list<CNPC *>* (CCharacterMgr::*)(CMapRes* mapRes)> CCharacterMgr::_GetWarpNpcList;
	static hook_method<void (CCharacterMgr::*)(int mapID, int guildID, int target)> CCharacterMgr::_Flush;
	static hook_method<int (CCharacterMgr::*)(void)> CCharacterMgr::_GetSkillSize;
	static hook_method<void (CCharacterMgr::*)(void)> CCharacterMgr::_InitLotto;
	static hook_method<short (CCharacterMgr::*)(CCharacter* src, CCharacter* dest)> CCharacterMgr::_GetDistance;
	static hook_method<int (CCharacterMgr::*)(const int in_MapID)> CCharacterMgr::_KickPlayerInMap;
	static hook_method<CPC* (CCharacterMgr::*)(const int in_MapID)> CCharacterMgr::_GetOnePlayerInMap;
	static hook_method<void (CCharacterMgr::*)(const char* mapName)> CCharacterMgr::_FinalDungeon_Skill;
	static hook_method<void (CCharacterMgr::*)(const char* mapName)> CCharacterMgr::_FinalDungeon_Item;
	static hook_method<void (CCharacterMgr::*)(const char* mapName)> CCharacterMgr::_FinalDungeon_NpcEvent;
	static hook_method<void (CCharacterMgr::*)(const char* mapName)> CCharacterMgr::_FinalDungeon_Npc;
	static hook_method<void (CCharacterMgr::*)(void)> CCharacterMgr::_BroadCastReAssemblyCertify;
	static hook_method<CNPC* (CCharacterMgr::*)(unsigned char type)> CCharacterMgr::_AllocNPC;
	static hook_method<CNPC* (CCharacterMgr::*)(unsigned long AID)> CCharacterMgr::_FindNPCByAID;
	static hook_method<CItem* (CCharacterMgr::*)(unsigned long AID)> CCharacterMgr::_SearchItem;
	static hook_method<CSkill* (CCharacterMgr::*)(unsigned long AID)> CCharacterMgr::_SearchSkill;
	static hook_method<void (CCharacterMgr::*)(unsigned long AID, int index, unsigned long connectionTime)> CCharacterMgr::_AddPCToIndexInfo;
	static hook_method<CCharacter* (CCharacterMgr::*)(unsigned long AID)> CCharacterMgr::_SearchPCFromIndexInfo;
	static hook_method<void (CCharacterMgr::*)(unsigned long AID)> CCharacterMgr::_DeletePCFromIndexInfo;
	static hook_method<void (CCharacterMgr::*)(CPC* pc)> CCharacterMgr::_OnDisconnect;
	static hook_method<void (CCharacterMgr::*)(CPC* pc)> CCharacterMgr::_OnDisconnect_STEP_NONE;
	static hook_method<void (CCharacterMgr::*)(CPC* pc)> CCharacterMgr::_OnDisconnect_STEP_REMOVE;
	static hook_method<void (CCharacterMgr::*)(CPC* pc)> CCharacterMgr::_OnDisconnect_STEP_ARRANGE;
	static hook_method<void (CCharacterMgr::*)(CPC* const pc)> CCharacterMgr::_OnDisconnect_STEP_ASYNCDB_SAVE_REQUEST;
	static hook_method<void (CCharacterMgr::*)(CPC* pc)> CCharacterMgr::_OnDisconnect_STEP_COMPLETE;
	static hook_method<void (CCharacterMgr::*)(CPC* pc)> CCharacterMgr::_OnDisconnect_STEP_ASYNCDB_SAVE_COMPLETE;
	static hook_method<int (CCharacterMgr::*)(CPC* pc)> CCharacterMgr::_IsSendable;

	friend class CPCPacketHandler;
};
